Prevod Miloje Arnautovic Prvi
Троструки наводници означавају вишередни низ. Све између почетног и завршног наводника део је једног стринга, укључујући повратак терета, водећи бели размак, и остале наводне карактере. Можете их користити било где, али видећете их најчешће када се користе за дефинисање docstring-а. Троструки наводници су такође лак начин за дефинисање стринга са појединачним и двоструким наводницима, као qq/.../ у Перлу 5. Све између троструких навода је функцијин docstring, који документује шта функција ради. А docstring, ако постоји, мора бити прва ствар дефинисана у функцији (то јест, у следећем реду након функције декларације). Не морате технички давати својој функцији docstring, али увек бисте требали. Знам да сте то чули на сваком часу програмирања икад, али Пајтон вам даје додатни подстицај: docstring је доступан током извођења као атрибут функције. ☞ Многи Пајтонови ИДЕ-ови користе docstring да би пружили документацију осетљиву на контекст да када укуцате име функције, њен docstring се појављује као опис. Ово може бити невероватно корисно, али добро је само као и документи које напишете. 1.4 '''import претраживачка путања Пре него што наставим, желим укратко споменути пут претраживања библиотеке. Пајтон тражи на више места када покушате да увезете модул. Тачније, тражи у свим директоријумима који су дефинисани у sys.path Ово је само листа, а можете је лако прегледати или модификовати са стандардним методама листе. (Сазнаћете више о листама у Native Datatypes.) >>> import sys ① >>> sys.path ② [, '/usr/lib/python31.zip', '/usr/lib/python3.1', '/usr/lib/python3.1/plat-linux2@EXTRAMACHDEPPATH@', '/usr/lib/python3.1/lib-dynload', '/usr/lib/python3.1/dist-packages', '/usr/local/lib/python3.1/dist-packages'] >>> sys ③ >>> sys.path.insert(0, '/home/mark/diveintopython3/examples') ④ >>> sys.path ⑤ '', '/usr/lib/python31.zip', '/usr/lib/python3.1', '/usr/lib/python3.1/plat-linux2@EXTRAMACHDEPPATH@', '/usr/lib/python3.1/lib-dynload', '/usr/lib/python3.1/dist-packages', '/usr/local/lib/python3.1/dist-packages' 1. Увозом sys модула све његове функције и атрибути постају доступни 2. sys.path је листа имена директорија која чине тренутни пут претраге. (Ваша ће изгледати другачије, зависно од вашег оперативног система, коју верзију Пајтона покрећете и где је првобитно инсталирана.) Пајтон ће потражити у овим директоријумима (овим редоследом) .py датотеку чије се име поклапа са оним које покушавате да увезете. 3. Уствари, лагао сам; истина је сложенија од тога, јер се не чувају сви модули као .py датотеке. Неки, попут sys модула, су уграђени модули; они су заправо уграђени у сам Пајтон. Уграђени модули се понашају као и обични модули, али њихов изворни Пајтон код није доступан, јер они нису написани на Пајтону-у! (sys модул је написан у Це-у.) 4. Можете да додате нови директоријум у Пајтон-овом путу претраживања током извођења додавањем имена директоријума у sys.path, и онда ће Пајтон и у том директоријуму потражити сваки пут кад покушате да увезете модул. Ефекат траје све док се Пајтон не затвори. 5. Користећи sys.path.insert(0, new_path), уметнули сте нови директоријум као прву ставку sys.path листе, и то на почетку Пајтоновог пута претраге. То је скоро увек оно што желите. У случају сукоба у именовању (на пример, ако Пајтон испоручује са верзијом 2 одређене библиотеке, али ви желите да користите верзију 3), ово осигурава да ће се ваши модули наћи и користити уместо модула који су дошли са Пајтон-ом. '''1.5 'Све је објекат''' У случају да сте пропустили, управо сам рекао да Пајтон функције имају атрибуте и да су ти атрибути доступни током извођења. Функција је, као и све остало у Пајтону, објекат. Покрените интерактивни Пајтон shell и урадите следеће: >>> import humansize ① >>> print(humansize.approximate_size(4096, True)) ② 4.0 KiB >>> print(humansize.approximate_size.__doc__) ③ Convert a file size to human-readable form. Keyword arguments: size -- file size in bytes a_kilobyte_is_1024_bytes -- if True (default), use multiples of 1024 if False, use multiples of 1000 Returns: string 1. Први ред увози humansize програм као модул - комад кода који можете интерактивно користити, или из већег Пајтон програма. Једном када увезете модул, можете показати било коју од његових јавних функција, класа или атрибута. Модули могу ово да ураде да би приступили функционалности других модула, и ви то можете учинити у интерактивном Пајтон shell-у такође. Ово је важан концепт и видећете још много више овога у овој књизи. 2. Кад желите користити функције дефинисане у увеженим модулима, морате унети назив модула. Тако да не можете да написати само approximate_size; мора бити humansize.approximate_size. Ако сте ишли на часове Јаве, ово би требало да вам буде познато. 3. Уместо да назовете функцију онако како бисте очекивали, затражили сте један од атрибута функције, __doc__. ☞ import у Пајтону је као require у Перлу. Када сте увезли (import) Пајтон модул, можете приступити његовим функцијама са module.function; када тражите (require) Перл модул, можете приступити његовим фукцијама са module::function. 1.5.1 '''Шта је објекат? Све у Пајтон-у је објект, и све може имати атрибуте и методе. Све функције имају уграђени атрибут __doc__, који враћа docstring дефинисан у изворном коду функције. Sys модул је објекат који има (између осталог) атрибут који се зове стаза. И тако даље. Ипак, то није одговор на темељније питање: шта је објекат? Различити програмски језици су дефинисали „објекат“ на различите начине. У неким, то значи да сви објекти морају имати атрибуте и методе; у другима, то значи да су сви предмети подкласификовани. У Пајтон-у је дефиниција лабавија. Неки предмети немају ни атрибуте ни методе, али могу да имају. Нису сви предмети подкласификовани. Али све је објекат у смислу да се може доделити променљивој или проследити као аргумент функцији. Можда сте чули за појам „првокласни објекат“ у другим програмерским контекстима. У Пајтон-у су функције првокласни објекти. Можете проследити функцију као аргумент другој функцији. Модули су првокласни објекти. Можете проследити читав модул као аргумент функцији. Класе су првокласни објекти и индивидуалне инстанце класе су такође првокласни објекти. Ово је важно, тако да ћу поновити у случају да сте пропустили првих неколико пута: све у Пајтон-у је објекат. Стрингови су предмети. Листе су предмети. Функције су објекти. Класе су предмети. Инстанце класе су објекти. Чак су и модули објекти. 1.6. Увлачење кода Пајтон функције немају експлицитни почетак или крај и немају витичасте заграде за обележавање места где код функције почиње и где се зауставља. Једини разделник је двотачка (:) и увлачење самог кода. def approximate_size(size, a_kilobyte_is_1024_bytes=True): ① if size < 0: ② raise ValueError('number must be non-negative') ③ ④ multiple = 1024 if a_kilobyte_is_1024_bytes else 1000 for suffix in SUFFIXESmultiple: ⑤ size /= multiple if size < multiple: return '{0:.1f} {1}'.format(size, suffix) raise ValueError('number too large') 1. Блокови кода су дефинисани увлачењем. Под „блоком кода“ мислим на функције, if наредбе, for петље, while петље и тако даље. Увлачење започиње блок, а уклањање увлачења завршава. Нема изричите заграде, или кључне речи. То значи да је бели простор значајан и да мора бити доследан. У овом примеру код функције је разведен у четири размака. Не морају бити четири простора, само треба бити доследан. Први ред који није увучен означава крај функције. 2. У Пајтон-у, наредбу if прати блок кода. Ако је израз if оцењен истинитим, увучени блок се извршава, у супротном пада на други блок (ако постоји уопште). Имајте на уму недостатак заграда у изразу. 3. Ова линија је унутар блока if. Ова изјава о повишењу створиће изузетак (типа ValueError), али само ако је величина <0. 4. Ово није крај функције. Потпуно празне линије се не рачунају. Они могу направити читљивији код, али се не рачунају као ограничивачи блока кода. Функција се наставља у следећем реду. 5. Петља for такође означава почетак блока кода. Блокови кода могу да садрже више линија, све док су они су сви увучени у истом износу. Ова петља има три кода у себи. Нема друге посебне синтаксе за вишередне блокове кодова. Само увуците и наставите са својим животом. Након почетног вређања Фортрана, склопићете мир са овим и видећете његове предности. Главна предност је што сви Пајтон програми изгледају слично, јер је увлачење захтев језика, а не ствар стила. То олакшава читање и разумевање Пајтон кода других људи. ☞ Пајтон користи враћање преноса да би одвојио изјаве и двотачку и увлачење да би одвојио засебне блокове кода. Це ++ и Јава користе тачке са зарезима за одвајање изјава и витичасте заграде да одвоје блокове кодова. 1.7 '''Изузеци Изузеци су свуда у Пајтон-у. Виртуелно сваки модул у стандардној Пајтон библиотеци их користи и сам Питхон ће их користити у много различитих околности. Видећете их више пута у овој књизи. Шта је изузетак? Обично је то грешка, показатељ да постоји нека грешка. (Нису сви изузеци грешке, али за сада то заборавите.) Неки програмски језици подстичу употребу кодова за повратак грешака које проверавате. Пајтон подстиче употребу изузетака са којима се бавите. Када се догоди грешка у Пајтон Shell-у, он штампа неке детаље о изузетку и како се то догодило, и то је то. То се назива нерешеним изузетком. Кад је настао изузетак, није постојао код који би га изричито приметио и бавио се њиме, па је поново продирао на врх Пајтон Shell-а, који избацује неке информације о отклањању грешака тако остави. У Shell-у, то није велика ствар, али ако се то догодило док је ваш Пајтон програм покренут, цео програм би дошао до кључања ако ништа не среди изузетак. Можда је то баш оно што желиш, можда није. ☞ За разлику од Јаве, Пајтон функције не декларишу изузетке које би могле да подигну. До тебе је да утврдиш који су могући изузеци које мораш ухватити. Изузетак не мора да резултира потпуним падом програма. Изузеци се могу решити. Изузетак је понекад то што имате грешку у коду (као што је приступ променљивој која не постоји), а понекад је изузетак нешто што можете предвидети. Ако отворите датотеку, можда не постоји. Ако увозите модул, он можда није инсталиран. Ако се повезујете са базом података, можда је недоступна или можда немате исправне безбедносне податке да бисте му приступили. Ако знате линију кода која може да подигне изузетак, требало би да поступате са изузетком користећи try...except блока. ☞ Питхон користи try...except блок за решавање изузетака и raise изјаву да их генеришу. Јава и Ц ++ користе try...catch блокове за решавање изузетака и throw изјаву да их генерише. Функција approximate_size() подиже изузетке у два различита случаја: ако је дата величина већа од које је функција дизајнирана да рукује или ако је мања од нуле. if size < 0: raise ValueError('number must be non-negative') Синтакса за подизање изузетака једноставна. Користите изјаву raise, коју прати име изузетка и опциони стринг који могу људи разумети за потребе уклањања погрешака. Синтакса подсећа на позивање функција. (У стварности, изузеци се имплементирају као класе, а ова изјава raise заправо ствара једну инстанцу класе ValueError и прослеђује стринг 'number must be non-negative' на његову иницијализациону метод. Али отишли смо далеко!) ☞ Не морате да решавате изузетак у функцији која га подиже. Ако га једна функција не решава, изузетак се преноси на функцију која га позива, па на фукцију која позива ту функцију и тако даље. Ако се изузетак никада не реши, ваш програм ће се срушити, Пајтон ће исписати “traceback”на стандардну грешку и то је крај тога. Опет, можда је баш то оно што желите; зависи од вашег програма. 1.7.1 '''Хватање import грешака Један од уграђених изузетака Пајтона је ImportError, који се покреће када покушате да увезете модул и не успете. То се може догодити из више разлога, али најједноставнији је случај кад модул не постоји у вашој путањи за увоз. Ово можете да користите да бисте у програм укључили опционе функције. На пример, the chardet библиотека пружа аутоматско детектовање кодирања знакова. Можда ваш програм жели да користи ову библиотеку ако постоји, али наставите пажљиво ако га корисник није инсталирао. То можете да урадите помоћу try..except блока. try: import chardet except ImportError: chardet = None После можете да проверите присуство chardet једноставном if изјавом: if chardet: # do something else: # continue anyway Још једна уобичајена употреба изузетка ImportError је када два модула имплементирају заједнички API, али једна је пожељнија од друге. (Можда је брже или користи мање меморије.) Можете да покушате да увезете један модул, али вратићете се на други модул ако први увоз не успе. На пример, XML поглавље говори о два модула који имплементирају заједнички API, који се назива ElementTree API. Први, lxml, је засебни модул који морате сами да преузмете и да инсталирате. Други, xml.etree.ElementTree, је спорији, али је део стандардне Пајтон 3 библиотеке. try: from lxml import etree except ImportError: import xml.etree.ElementTree as etree На крају овог try..except блока, увели сте неки модул и назвали га етрее. Пошто оба модула имплементирају заједнички API, остатак кода не треба стално да проверава који модул је увезен. А будући да се модул који је увезен увек назива етрее, остатак вашег кода не треба бити затрпан if изјавама да би позивао другачије именоване модуле. 1.8. '''Невезане променљиве Погледајте још једном ову линију кода из approximate_size() функције: multiple = 1024 if a_kilobyte_is_1024_bytes else 1000 Ви уопште нисте дефинисали променљиву multiple, само сте јој доделите вредност. То је у реду, јер Пајтон вам омогућава то. Оно што вам Пајтон неће дозволити јесте позив на променљиву којој никада није додељена вредност. Покушај да се то учини створиће изузетак NameError. >>> x Traceback (most recent call last): File "< stdin>", line 1, in < module> NameError: name 'x' is not defined >>> x = 1 >>> x 1 Једног дана ћете се захвалити Пајтону због овога. 1.9 '''Све је осетљиво на мало и велико слово Сва имена у Пајтону осетљива на мало и велико слово: имена променљивих, имена функција, имена класа, имена модула, имена изузетака. Ако можете да га добијете, поставите, позовете, конструктујете, увезете, или подигнете, осетљиво је на мало и велико слово. >>> an_integer = 1 >>> an_integer 1 >>> AN_INTEGER Traceback (most recent call last): File "< stdin>", line 1, in < module> NameError: name 'AN_INTEGER' is not defined >>> An_Integer Traceback (most recent call last): File "< stdin>", line 1, in < module> NameError: name 'AN_INTEGER' is not defined >>> an_inteGer Traceback (most recent call last): File "< stdin>", line 1, in < module> NameError: name 'AN_INTEGER' is not defined И тако даље. 1.10. '''RUNNING скрипте Пајтон модули су објекти и имају неколико корисних атрибута. Можете користити ово да лако тестирате своје модуле док их пишете, тако што ћете укључити специјалан блок кода који се извршава када покренете Пајтон датотеку на командној линији. Погледајте последњих пар линија од humansize.py: if __name__ '__main__': print(approximate_size(1000000000000, False)) print(approximate_size(1000000000000)) ☞ Као и Це, Пајтон користи за упоређивање и = за додељивање. За разлику од Це-а, Пајтон не подржава додељивање у линији, тако да нема шансе ћете случајно доделити вредност коју сте хтели да упоредите. Па шта чини ову if изјаву посебном? Па, модули су објекти, а сви модули имају уграђен атрибут __name__. Модулов __name__ зависи од тога како користите тај модул. Ако ви увезете модул, онда је __name__ име фајла тог модула, без путање до директоријума или наставка фајла. >>> import humansize >>> humansize.__name__ 'humansize' Али ви можете такође покренути модул као самостални програм, у којем ће случају __name__ бити посебна подразумевана вредност, __main__. Пајтон ће проценити ову if наредбу, пронаћи прави израз и извршити if кодни блок. У овом случају, да се одштампају две вредности. c:\home\diveintopython3> c:\python31\python.exe humansize.py 1.0 TB 931.3 GiB И то је ваш први Пајтон програм!